package com.xindong.paking.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xindong.paking.dtos.*;
import com.xindong.paking.entity.TbBalance;
import com.xindong.paking.entity.TbUser;
import com.xindong.paking.exception.CustomerException;
import com.xindong.paking.mapper.TbBalanceMapper;
import com.xindong.paking.mapper.TbUserMapper;
import com.xindong.paking.service.TbBalanceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xindong.paking.utils.Result;
import com.xindong.paking.utils.UserInfoUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author wenbo
 * @since 2023-01-11
 */
@Service
public class TbBalanceServiceImpl extends ServiceImpl<TbBalanceMapper, TbBalance> implements TbBalanceService {

    @Autowired
    private TbBalanceMapper tbBalanceMapper;

    @Autowired
    private TbUserMapper tbUserMapper;

    @Override
    public Result add(TbBalance tbBalance) {

        // 设置更改时间
        tbBalance.setUpdateTime(LocalDateTime.now());

        // 设置余额为0
        tbBalance.setBalance(0.0);

        // 设置积分为0
        tbBalance.setIntegral(0);

        int insert = tbBalanceMapper.insert(tbBalance);

        if (insert == 0) {
            throw new CustomerException("新增余额失败");
        }

        return Result.success("新增余额成功");
    }

    @Override
    public Result delete(Integer id) {

        int delete = tbBalanceMapper.deleteById(id);

        if (delete == 0) {
            throw new CustomerException("删除余额失败");
        }

        return Result.success("删除余额成功");
    }

    @Override
    public Result update(TbBalance tbBalance) {

        tbBalance.setUpdateTime(LocalDateTime.now());

        int update = tbBalanceMapper.updateById(tbBalance);

        if (update == 0) {
            throw new CustomerException("余额更新失败");
        }

        return Result.success("余额更新成功");
    }

    @Override
    public Result list(TbBalanceListParams params) {

        // 设置分页
        IPage<TbBalance> iPage = new Page<>(params.getPage(), params.getPageSize());

        // 设置所有参数可查询
        TbBalance tbBalance = new TbBalance();
        BeanUtils.copyProperties(params, tbBalance);
        QueryWrapper<TbBalance> wrapper = new QueryWrapper<>();
        wrapper.setEntity(tbBalance);

        // 进行查询
        IPage<TbBalance> page = tbBalanceMapper.selectPage(iPage, wrapper);

        // 封装返回对象
        ArrayList<TbBalanceDTO> tbBalanceDTOS = new ArrayList<>();
        List<TbBalance> records = page.getRecords();
        for (TbBalance record : records) {
            // 获取对应用户的名字
            TbUser tbUser = tbUserMapper.selectById(record.getUserId());
            // 返回参数
            TbBalanceDTO tbBalanceDTO = new TbBalanceDTO();
            BeanUtils.copyProperties(record, tbBalanceDTO);
            tbBalanceDTO.setUsername(tbUser.getUsername());
            tbBalanceDTO.setRealname(tbUser.getRealname());

            tbBalanceDTOS.add(tbBalanceDTO);
        }

        // 设置返回参数
        PageResult pageResult = new PageResult(tbBalanceDTOS, page.getTotal(), params.getPage(), params.getPageSize());

        return Result.success("查询成功", pageResult);
    }

    @Override
    public Result recharge(Double money) {

        // 查询用户余额
        TbBalance userBalance = this.getUserBalance();

        // 获取当前余额，并进行充值
        Double balance = userBalance.getBalance();
        userBalance.setBalance(balance + money);

        // 进行更新
        Result result = this.update(userBalance);

        // 判断更新是否成功
        this.getStatus(result, "余额充值失败");

        return Result.success("余额充值成功");
    }

    @Override
    public Result deduction(Double money) {

        // 查询用户余额
        TbBalance userBalance = this.getUserBalance();

        // 获取当前余额，并进行扣款
        Double balance = userBalance.getBalance();

        if (money > balance) {
            throw new CustomerException("余额不足");
        }

        userBalance.setBalance(balance - money);

        // 进行更新
        Result result = this.update(userBalance);

        // 判断更新是否成功
        this.getStatus(result, "余额扣款失败");

        return Result.success("余额扣款成功");
    }

    @Override
    public Result pointsIncrease(Integer integral) {

        // 查询用户余额
        TbBalance userBalance = this.getUserBalance();

        // 添加用户积分
        Integer oldIntegral = userBalance.getIntegral();
        userBalance.setIntegral(oldIntegral + integral);

        // 进行更新
        Result result = this.update(userBalance);

        this.getStatus(result, "添加积分失败");

        return Result.success("添加积分成功");
    }

    @Override
    public Result pointsRedemption(Integer integral) {

        // 查询用户余额
        TbBalance userBalance = this.getUserBalance();

        // 如果积分不足
        Integer oldInteger = userBalance.getIntegral();
        if (integral > oldInteger) {
            throw new CustomerException("积分不足");
        }

        userBalance.setIntegral(oldInteger - integral);

        Result result = this.update(userBalance);
        this.getStatus(result, "积分兑换失败");

        return Result.success("积分兑换成功");
    }

    /**
     * 根据id查询用户余额
     * @param userId
     * @return
     */
    @Override
    public Result selectMoneyByUserId(Integer userId) {
        LambdaQueryWrapper<TbBalance> tbBalanceLambdaQueryWrapper = new LambdaQueryWrapper<>();
        tbBalanceLambdaQueryWrapper.eq(TbBalance::getUserId, userId);
        TbBalance tbBalance = tbBalanceMapper.selectOne(tbBalanceLambdaQueryWrapper);
        MoneyDTO moneyDTO = new MoneyDTO();
        BeanUtils.copyProperties(tbBalance, moneyDTO);
        return Result.success("获取成功", moneyDTO);
    }

    /**
     * 根据id查询用户积分
     * @param userId
     * @return
     */
    @Override
    public Result selectIntegralByUserId(Integer userId) {
        LambdaQueryWrapper<TbBalance> tbBalanceLambdaQueryWrapper = new LambdaQueryWrapper<>();
        tbBalanceLambdaQueryWrapper.eq(TbBalance::getUserId, userId);
        TbBalance tbBalance = tbBalanceMapper.selectOne(tbBalanceLambdaQueryWrapper);
        IntegralDTO integralDTO = new IntegralDTO();
        BeanUtils.copyProperties(tbBalance, integralDTO);
        return Result.success("获取成功", integralDTO);
    }

    /**
     * 根据id增加余额
     * @param tbBalance
     * @return
     */
    @Override
    public Result addMoneyByUserId(TbBalance tbBalance) {
        LambdaQueryWrapper<TbBalance> tbBalanceLambdaQueryWrapper = new LambdaQueryWrapper<>();
        tbBalanceLambdaQueryWrapper.eq(TbBalance::getUserId, tbBalance.getUserId());
        TbBalance tbBalance1 = tbBalanceMapper.selectOne(tbBalanceLambdaQueryWrapper);
        tbBalance1.setBalance(tbBalance1.getBalance() + tbBalance.getBalance());
        tbBalance1.setUpdateTime(LocalDateTime.now());
        tbBalanceMapper.updateById(tbBalance1);
        return Result.success("更新成功");
    }

    /**
     * 根据id增加积分
     * @param tbBalance
     * @return
     */
    @Override
    public Result addIntegralByUserId(TbBalance tbBalance) {
        LambdaQueryWrapper<TbBalance> tbBalanceLambdaQueryWrapper = new LambdaQueryWrapper<>();
        tbBalanceLambdaQueryWrapper.eq(TbBalance::getUserId, tbBalance.getUserId());
        TbBalance tbBalance1 = tbBalanceMapper.selectOne(tbBalanceLambdaQueryWrapper);
        tbBalance1.setIntegral(tbBalance1.getIntegral() + tbBalance.getIntegral());
        tbBalance1.setUpdateTime(LocalDateTime.now());
        tbBalanceMapper.updateById(tbBalance1);
        return Result.success("更新成功");
    }

    public TbBalance getUserBalance() {

        // 获取用户id
        Map<String, Object> userInfo = UserInfoUtil.getUserInfo();
        Integer id = (Integer)userInfo.get("id");

        // 查询用户余额
        QueryWrapper<TbBalance> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", id);
        TbBalance userBalance = tbBalanceMapper.selectOne(wrapper);

        return userBalance;
    }

    public void getStatus(Result result, String message) {

        // 判断更新是否成功
        int status = result.getStatus();
        if (status == 400) {
            throw new CustomerException("余额扣款失败");
        }

    }
}
